home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_asm
/
dasm48
/
dasm48.asm
< prev
next >
Wrap
Assembly Source File
|
1986-07-21
|
30KB
|
1,048 lines
.XALL
PAGE ,132
TITLE DASM48 - 14 SEP 1985
; ****************************************************************
; ** **
; ** MS-DOS 8048 DISASSEMBLER **
; ** **
; **............................................................**
; ** **
; ** DASM48 DISASSEMBLES 8048 INTEL HEX FILES. **
; ** **
; ****************************************************************
; ..... MODULE CONNECTION POINTS .....
EXTRN MNEM:NEAR ; MNEMONIC TABLE
EXTRN BYTES:NEAR ; BYTES TABLE
; ..... MACROS .....
DISKRD MACRO NUMBYTE ; READ SPECIFIED NUMBER OF BYTES FROM DISK
LOCAL OK ; OK IS A LOCAL SYMBOL
MOV AH,READ ; LOAD READ COMMAND
MOV BX,RDHAND ; LOAD READ FILE HANDLE
MOV CX,NUMBYTE ; LOAD NUMBER OF CHARACTERS TO BE READ
MOV DX,OFFSET DSKBUF; POINT TO DISK BUFFER
INT DOSFUNC ; READ FROM INPUT FILE - ERROR?
JNC OK ; NO - DONE
JMP DSKERR ; YES - DISPLAY ERROR
OK:
ENDM ;
DISKWR MACRO NUMBYTE ; WRITE SPECIFIED NUMBER OF BYTES TO DISK
LOCAL OK ; OK IS A LOCAL SYMBOL
MOV AH,WRITE ; LOAD WRITE COMMAND
MOV BX,WRHAND ; LOAD WRITE FILE HANDLE
MOV CX,NUMBYTE ; LOAD NUMBER OF CHARACTERS TO WRITE
MOV DX,OFFSET DSKBUF; POINT TO DISK BUFFER
INT DOSFUNC ; WRITE TO OUTPUT - ERROR?
JNC OK ; NO - DONE
JMP DSKERR ; YES - DISPLAY ERROR
OK:
ENDM ;
PAGE
; ..... DOS COMMANDS .....
DOSFUNC EQU 21H ; DOS FUNCTION INTERRUPT
PR_STR EQU 09H ; DOS FUNCTION PRINT STRING COMMAND
CREATE EQU 3CH ; CREATE FILE COMMAND
OPEN EQU 3DH ; OPEN FILE COMMAND
CLOSE EQU 3EH ; CLOSE FILE COMMAND
READ EQU 3FH ; READ FILE COMMAND
WRITE EQU 40H ; WRITE FILE COMMAND
RDACC EQU 0 ; READ FILE ACCESS CODE
WRACC EQU 1 ; WRITE FILE ACCESS CODE
WRATT EQU 0 ; WRITE FILE ATTRIBUTE CODE
; ..... CONSTANTS .....
MEMLEN EQU 2000H ; LENGTH OF MEMORY BUFFER
MAXLEN EQU 80 ; MAXIMUM FILE NAME LENGTH
CR EQU 0DH ; ASCII <CR>
LF EQU 0AH ; ASCII LINE FEED
RS EQU 1EH ; ASCII RECORD SEPARATOR
TAB EQU 09H ; ASCII TAB
DATIND EQU 00H ; HEX FILE DATA RECORD INDICATOR
EOFIND EQU 01H ; HEX FILE END OF FILE INDICATOR
PAGE
STACK SEGMENT STACK ; STACK SEGMENT
DW 1024 DUP (?) ; 1024 LEVELS OF STACK
STACK ENDS
DATA SEGMENT PUBLIC ; DATA SEGMENT
; ****************************************************************
; ** **
; ** MISCELLANEOUS STRINGS **
; ** **
; ****************************************************************
MSGORG DB ';',CR,LF,TAB,'ORG',TAB,'0'
LENORG EQU $-MSGORG
MSGEND DB ';',CR,LF,TAB,'END',CR,LF
LENEND EQU $-MSGEND
; ****************************************************************
; ** **
; ** ERROR STRINGS **
; ** **
; ****************************************************************
MBCOM DB CR,LF,'COMMAND LINE ERROR',CR,LF,LF,'$'
MBHEX DB CR,LF,'BAD HEX DATA',CR,LF,LF,'$'
MDISK0 DB CR,LF,'ERROR 0 - DISK FULL',CR,LF,LF,'$'
MDISK1 DB CR,LF,'ERROR 1 - INVALID FUNCTION',CR,LF,LF,'$'
MDISK2 DB CR,LF,'ERROR 2 - FILE NOT FOUND',CR,LF,LF,'$'
MDISK3 DB CR,LF,'ERROR 3 - PATH NOT FOUND',CR,LF,LF,'$'
MDISK4 DB CR,LF,'ERROR 4 - TOO MANY OPEN FILES',CR,LF,LF,'$'
MDISK5 DB CR,LF,'ERROR 5 - ACCESS DENIED',CR,LF,LF,'$'
MDISK6 DB CR,LF,'ERROR 6 - INVALID FILE HANDLE',CR,LF,LF,'$'
MUKNOW DB CR,LF,'UNKNOWN DISK ERROR',CR,LF,LF,'$'
PAGE
; ****************************************************************
; ** **
; ** PROGRESS MESSAGE STRINGS **
; ** **
; ****************************************************************
MRCOM DB CR,LF,'READING COMMAND LINE',CR,LF,'$'
MOPENR DB 'OPENING READ FILE',CR,LF,'$'
MCHEX DB 'CONVERTING HEX FILE',CR,LF,'$'
MOPENW DB 'CLOSING READ AND OPENING WRITE FILE',CR,LF,'$'
MDISS DB 'DISASSEMBLING CONVERTED DATA',CR,LF,'$'
MCLOSW DB 'CLOSING WRITE FILE',CR,LF,'$'
MEXIT DB 'EXITING TO DOS',CR,LF,LF,'$'
PAGE
; ****************************************************************
; ** **
; ** MEMORY ASSIGNMENTS **
; ** **
; ****************************************************************
DSKBUF DB 80 DUP (?) ; DISK I/O BUFFER
DSKCNT DW (?) ; DISK BUFFER COUNTER
RDFILE DB MAXLEN+1 DUP (0); INPUT FILE NAME BUFFER
WRFILE DB MAXLEN+1 DUP (0); OUTPUT FILE NAME BUFFER
RDHAND DW (?) ; READ FILE HANDLE
WRHAND DW (?) ; WRITE FILE HANDLE
CHKACC DB (?) ; CHECKSUM ACCUMULATOR
DSKPTR DW (?) ; DISK BUFFER POINTER
MEMPTR DW (?) ; MEMORY POINTER
MEMCNT DW (?) ; MEMORY COUNTER
NUMREC DW (?) ; NUMBER OF RECORDS IN CURRENT LINE
RECNUM DW (?) ; NUMBER OF BYTES FOR NUMREC RECORDS
CURADD DW (?) ; CURRENT ADDRESS STORAGE
DB (0) ; DUMMY START OF MEMBUF
MEMBUF DB MEMLEN DUP (0) ; MEMORY BUFFER
DATA ENDS
PAGE
CODE SEGMENT ; CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
; ****************************************************************
; ** **
; ** MAIN PROGRAM **
; ** **
; ****************************************************************
DASM48 PROC FAR ;
PUSH DS ;
MOV AX,0 ;
PUSH AX ; SET UP FOR A FAR RETURN TO DOS
MOV AX,DATA ;
MOV DS,AX ; SET UP DATA SEGMENT REGISTER
MOV DX,OFFSET MRCOM ; POINT TO READING COMMAND LINE MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL RCMD ; READ COMMAND LINE
MOV DX,OFFSET MOPENR; POINT TO OPENING INPUT FILE MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL OPENRD ; OPEN INPUT FILE FOR READ
MOV DX,OFFSET MCHEX ; POINT TO CONVERTING HEX FILE MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL CHEX ; CONVERT INPUT FILE
MOV DX,OFFSET MOPENW; POINT TO OPENING OUTPUT FILE MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL OPENWR ; OPEN OUTPUT FILE FOR WRITE
MOV DX,OFFSET MDISS ; POINT TO DISASSEMBLING MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL DISS ; DISASSEMBLE FILE
MOV DX,OFFSET MCLOSW; POINT TO CLOSING WRITE FILE MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
CALL CLOSWR ; DISASSEMBLE FILE
MOV DX,OFFSET MEXIT ; POINT TO EXITING MESSAGE
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
RET ; RETURN TO DOS
DASM48 ENDP ;
PAGE
; ****************************************************************
; ** **
; ** READ COMMAND LINE **
; ** **
; ****************************************************************
RCMD PROC NEAR ;
MOV BX,80H ; POINT TO NUMBER OF RECEIVED CHARACTERS
MOV CH,ES:[BX] ; LOAD NUMBER OF RECEIVED CHARACTERS
OR CH,CH ; ZERO CHARACTERS?
JZ RCMD25 ; YES - DISPLAY ERROR
INC BX ; NO - POINT TO CHARACTERS
MOV DI,OFFSET RDFILE; POINT TO INPUT FILE NAME BUFFER
MOV CL,MAXLEN ; LOAD MAXIMUM FILE NAME LENGTH
MOV AL,ES:[BX] ; READ NEXT CHARACTER
INC BX ; ADVANCE POINTER
DEC CH ; RETARD CHARACTER COUNTER - END?
JZ RCMD25 ; YES - DISPLAY ERROR
CMP AL,' ' ; NO - SPACE?
JNZ RCMD25 ; NO - DISPLAY ERROR
RCMD05:
MOV AL,ES:[BX] ; YES - READ NEXT CHARACTER
MOV [DI],AL ; WRITE TO INPUT FILE NAME BUFFER
CMP AL,' ' ; SPACE?
JZ RCMD10 ; YES - LOAD OUTPUT FILE NAME
INC BX ; NO -
INC DI ; - ADVANCE POINTERS
DEC CH ; RETARD CHARACTER COUNTER - END?
JZ RCMD25 ; YES - DISPLAY ERROR
DEC CL ; NO - RETARD FILE NAME COUNTER - TOO LONG?
JZ RCMD25 ; YES - DISPLAY ERROR
JMP RCMD05 ; NO - CONTINUE
RCMD10:
INC BX ; ADVANCE COMMAND LINE POINTER
DEC CH ; DECREMENT CHARACTER COUNTER - END?
JZ RCMD25 ; YES - DISPLAY ERROR
MOV DI,OFFSET WRFILE; NO - POINT TO OUTPUT FILE NAME BUFFER
MOV CL,MAXLEN ; LOAD MAXIMUM FILE NAME LENGTH
RCMD20:
MOV AL,ES:[BX] ; READ NEXT CHARACTER
CMP AL,' ' ; SPACE?
JZ RCMD25 ; YES - DISPLAY ERROR
MOV [DI],AL ; NO - WRITE TO OUTPUT FILE NAME BUFFER
INC BX ;
INC DI ; ADVANCE POINTERS
DEC CH ; RETARD COUNTER - LAST CHARACTER?
JZ RCMD30 ; YES - DONE
DEC CL ; NO - RETARD COUNTER - FILE NAME TOO LONG?
JZ RCMD25 ; YES - DISPLAY ERROR
JMP RCMD20 ; NO - CONTINUE
RCMD25:
MOV DX,OFFSET MBCOM ; POINT TO BAD COMMAND LINE MESSAGE
JMP MISERR ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
RCMD30:
RET ;
RCMD ENDP ;
; ****************************************************************
; ** **
; ** OPEN INPUT FILE FOR READ **
; ** **
; ****************************************************************
OPENRD PROC NEAR ;
MOV AH,OPEN ; LOAD OPEN FILE COMMAND
MOV AL,RDACC ; LOAD READ ACCESS CODE
MOV DX,OFFSET RDFILE; POINT TO INPUT FILE NAME
INT DOSFUNC ; OPEN INPUT FILE - ERROR?
JNC OPRD05 ; NO - STORE READ FILE HANDLE
JMP DSKERR ; YES - DISPLAY ERROR
OPRD05:
MOV RDHAND,AX ; STORE READ FILE HANDLE
RET ; DONE
OPENRD ENDP
PAGE
; ****************************************************************
; ** **
; ** CONVERT INPUT FILE **
; ** **
; ****************************************************************
CHEX PROC NEAR ;
CHEX10:
DISKRD 1 ; READ ONE BYTE FROM DISK FILE - ERROR?
CMP AX,01 ; NO - 1 CHARACTER?
JZ CHEX11 ; YES - TEST FOR RECORD MARK
JMP CHEX25 ; NO - DISPLAY ERROR
CHEX11:
MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
MOV AL,[BX] ; LOAD RECEIVED CHARACTER
CMP AL,':' ; RECORD MARK?
JNZ CHEX10 ; NO - TRY AGAIN
DISKRD 8 ; YES - READ EIGHT BYTES FROM DISK FILE - ERROR?
MOV CHKACC,0 ; NO - INITIALIZE CHECKSUM ACCUMULATOR
CMP AX,08 ; RECEIVE 8 CHARACTERS?
JZ CHEX12 ; YES - CONVERT NUMBER OF BYTES IN RECORD
JMP CHEX25 ; NO - DISPLAY ERROR
CHEX12:
MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
CALL PACK ; CONVERT NUMBER OF BYTES IN RECORD
MOV AH,0 ;
MOV NUMREC,AX ; STORE
CALL PACK ; CONVERT HIGH START ADDRESS
MOV DH,AL ; STORE
CALL PACK ; CONVERT LOW START ADDRESS
MOV DL,AL ; STORE
CALL PACK ; CONVERT RECORD INDICATOR
CMP AL,DATIND ; DATA INDICATOR?
JNZ CHEX20 ; NO - TEST FOR END OF FILE INDICATOR
MOV BX,OFFSET MEMBUF; YES - POINT TO MEMBUF
ADD BX,DX ; COMPUTE MEMBUF ADDRESS FOR THIS RECORD
MOV MEMPTR,BX ; STORE
MOV AX,NUMREC ; LOAD NUMBER OF RECORDS
ADD AX,AX ; COMPUTE NUMBER OF DATA CHARACTERS
ADD AX,4 ; ADD CHECKSUM AND TERMINATOR CHARACTER COUNT
MOV RECNUM,AX ; STORE
DISKRD RECNUM ; YES - READ RECNUM BYTES FROM DISK FILE - ERROR?
MOV BX,OFFSET DSKBUF; NO - POINT TO DISK BUFFER
MOV DSKPTR,BX ; INITITIALIZE DISK BUFFER POINTER
CMP RECNUM,CX ; RECEIVED CORRECT NUMBER OF CHARACTERS?
JZ CHEX14 ; YES - CONVERT RECORD
JMP CHEX25 ; NO - DISPLAY ERROR
CHEX14:
MOV CX,NUMREC ; LOAD COUNTER
JCXZ CHEX21 ; ZERO BYTES? - YES - LOAD AND TEST
; CHECKSUM AND TERMINATOR
CHEX15:
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
CALL PACK ; CONVERT DATA
MOV DSKPTR,BX ; STORE DISK BUFFER POINTER
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV [BX],AL ; STORE DATA
INC MEMPTR ; ADVANCE MEMORY BUFFER POINTER
DEC CX ; RETARD COUNTER - DONE?
JNZ CHEX15 ; NO - CONTINUE
MOV BX,DSKPTR ; YES - LOAD DISK BUFFER POINTER
CALL PACK ; CONVERT CHECKSUM
MOV CL,AL ; STORE CHECKSUM
MOV AL,CHKACC ; LOAD CHECKSUM ACCUMULATOR
SUB AL,CL ; ADJUST CHECKSUM
NOT AL ;
INC AL ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
CMP AL,CL ; CHECKSUMS MATCH?
JNZ CHEX25 ; NO - DISPLAY ERROR
CMP BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
JNZ CHEX25 ; NO - DISPLAY ERROR
INC BX ; YES - POINT TO LINE FEED
CMP BYTE PTR[BX],LF ; LINE FEED?
JNZ CHEX25 ; NO - DISPLAY ERROR
JMP CHEX10 ; YES - CONTINUE
CHEX20:
CMP AL,EOFIND ; END OF FILE INDICATOR?
JNZ CHEX25 ; NO - DISPLAY ERROR
DISKRD 4 ; YES - READ 4 BYTES FROM DISK FILE - ERROR?
CMP AX,4 ; NO - 4 CHARACTERS?
JNZ CHEX25 ; NO - DISPLAY ERROR
CHEX21:
MOV BX,OFFSET DSKBUF; YES - POINT TO DISK BUFFER
CALL PACK ; CONVERT CHECKSUM
MOV CL,AL ; STORE CHECKSUM
MOV AL,CHKACC ; LOAD CHECKSUM ACCUMULATOR
SUB AL,CL ; ADJUST CHECKSUM
NOT AL ;
INC AL ; COMPUTE 2'S COMPLEMENT OF CHECKSUM
CMP AL,CL ; CHECKSUMS MATCH?
JNZ CHEX25 ; NO - DISPLAY ERROR
CMP BYTE PTR[BX],CR ; YES - TERMINATED WITH <CR>?
JNZ CHEX25 ; NO - DISPLAY ERROR
INC BX ; YES - POINT TO LINE FEED
CMP BYTE PTR[BX],LF ; LINE FEED?
JNZ CHEX25 ; NO - DISPLAY ERROR
RET ; YES - DONE
CHEX25:
MOV DX,OFFSET MBHEX ; POINT TO BAD HEX DATA MESSAGE
JMP MISERR ; DISPLAY ERROR MESSAGE AND EXIT TO DOS
CHEX ENDP ;
PAGE
; ****************************************************************
; ** **
; ** OPEN OUTPUT FILE FOR WRITE **
; ** **
; ****************************************************************
OPENWR PROC NEAR ;
MOV AH,CLOSE ; LOAD CLOSE FILE COMMAND
MOV BX,RDHAND ; LOAD INPUT FILE HANDLE
INT DOSFUNC ; CLOSE THE INPUT FILE - ERROR?
JNC OPWR05 ; NO - OPER WRITE FILE
JMP DSKERR ; YES - DISPLAY ERROR
OPWR05:
MOV AH,CREATE ; LOAD CREATE FILE COMMAND
MOV CX,WRATT ; LOAD WRITE FILE ATTRIBUTE
MOV DX,OFFSET WRFILE; POINT TO OUTPUT FILE NAME
INT DOSFUNC ; OPEN OUTPUT FILE - ERROR?
JNC OPWR10 ; NO - STORE WRITE FILE HANDLE
;
JMP DSKERR ; YES - DISPLAY ERROR
OPWR10:
MOV WRHAND,AX ; STORE WRITE FILE HANDLE
RET ; DONE
OPENWR ENDP ;
PAGE
; ****************************************************************
; ** **
; ** DISASSEMBLE MEMORY BUFFER **
; ** **
; ****************************************************************
DISS PROC NEAR ;
MOV BX,OFFSET MEMBUF-1; POINT TO MEMORY BUFFER
MOV MEMPTR,BX ; INITIALIZE MEMORY POINTER
MOV BX,MEMLEN+2 ; LOAD NUMBER OF BYTES TO DISSASEMBLE
MOV MEMCNT,BX ; STORE
DISS05:
MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
MOV DSKPTR,BX ; INITIALIZE DISK BUFFER POINTER
MOV BX,0 ;
MOV DSKCNT,BX ; CLEAR DISK BUFFER COUNTER
MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
DEC BX ; RETARD MEMORY BUFFER COUNTER - END OF FILE?
MOV MEMCNT,BX ; (STORE)
JZ DISS10 ; YES - WRITE "END" TO OUTPUT FILE
MOV BX,MEMPTR ; NO - LOAD MEMORY BUFFER POINTER
MOV AL,[BX] ; LOAD NEXT OPCODE
OR AL,AL ; ZERO?
JNZ DISS15 ; NO - FIND IT'S MNEMONIC
DISS10:
PUSH BX ; YES - SAVE MEMORY BUFFER POINTER
MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
DEC BX ; END OF FILE?
MOV MEMCNT,BX ; (STORE)
POP BX ; (RESTORE MEMORY POINTER)
JNZ DISS11 ; NO - POINT TO NEXT BYTE
JMP DISS65 ; YES - WRITE "END" TO DISK
DISS11:
INC BX ; POINT TO NEXT BYTE
MOV AL,[BX] ; LOAD IT
OR AL,AL ; ZERO?
JZ DISS10 ; YES - CONTINUE
MOV MEMPTR,BX ; NO - STORE MEMORY BUFFER POINTER
CALL ORGWR ; WRITE ORG LINE TO DISK
JMP DISS05 ; CONTINUE
DISS15:
MOV DX,BX ; LOAD CURRENT MEMORY BUFFER LOCATION
SUB DX,OFFSET MEMBUF; COMPUTE CURRENT ADDRESS
MOV CURADD,DX ; STORE
MOV CL,[BX] ;
MOV CH,0 ; LOAD OPCODE
INC CX ; ADJUST
MOV BX,OFFSET MNEM ; POINT TO MNEMONIC TABLE
DISS20:
DEC CX ; RETARD OPCODE - DONE?
JZ DISS30 ; YES - WRITE TAB TO DISK BUFFER
DISS25:
MOV AL,[BX] ; NO - LOAD NEXT CHARACTER
INC BX ; ADVANCE MNEMONIC TABLE POINTER
CMP AL,RS ; RS?
JZ DISS20 ; YES - RETARD OPCODE AND TEST FOR DONE
JMP DISS25 ; NO - TEST NEXT CHARACTER FOR RS
DISS30:
PUSH BX ; SAVE MNEMONIC POINTER
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
PUSH BX ;
POP DI ; LOAD DISK BUFFER POINTER IN DI
POP BX ; RESTORE MNEMONIC POINTER
DISS35:
MOV AL,[BX] ; LOAD MNEMONIC CHARACTER
CMP AL,RS ; RS?
JZ DISS40 ; YES - STORE DISK BUFFER POINTER
MOV [DI],AL ; NO - WRITE CHARACTER TO DISK BUFFER
INC DI ; ADVANCE DISK BUFFER POINTER
INC BX ; ADVANCE MNEMONIC POINTER
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
JMP DISS35 ; TEST NEXT CHARACTER FOR RS
DISS40:
XCHG BX,DI ; LOAD DISK BUFFER POINTER IN BX
MOV DSKPTR,BX ; STORE DISK BUFFER POINTER
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV CH,0 ;
MOV CL,[BX] ; LOAD OP-CODE
INC BX ; ADVANCE MEMORY BUFFER POINTER
MOV MEMPTR,BX ; STORE
CALL OPBYTE ; COMPUTE NUMBER OF BYTES FOR THIS OPCODE
MOV AL,CL ; LOAD NUMBER OF BYTES
OR AL,AL ; ZERO BYTES (UNDEFINED)?
JNZ DISS41 ; NO - TEST FOR ONE BYTE
MOV BX,MEMPTR ; YES - LOAD MEMORY BUFFER POINTER
DEC BX ; ADJUST
MOV AL,[BX] ; LOAD "OP-CODE"
MOV BX,DSKPTR ; LOAD DISK POINTER
MOV BYTE PTR[BX],'0'; WRITE LEADING ZERO TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
CALL EXPAND ; WRITE "OP-CODE" TO DISK BUFFER
MOV BX,DSKPTR ; LOAD DISK POINTER
MOV BYTE PTR[BX],'H'; WRITE "H" TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
ADD DSKCNT,2 ; ADVANCE DISK COUNTER
JMP DISS60 ; WRITE "TAB,;,CR,LF" TO OUTPUT FILE
DISS41:
DEC AL ; ONE BYTE?
JNZ DISS42 ; NO - TEST FOR TWO BYTES
JMP DISS60 ; YES - WRITE "TAB,;,CR,LF" TO OUTPUT FILE
DISS42:
DEC AL ; TWO BYTES?
JZ DISS45 ; YES - WRITE SECOND BYTE WITH LEADING ZERO
DEC AL ; NO - TWO BYTES WITH NO LEADING ZERO?
JZ DISS50 ; YES - WRITE SECOND BYTE
JMP DISS55 ; NO - WRITE PAGE NUMBER AND SECOND BYTE
DISS45:
MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
MOV MEMCNT,BX ; (STORE)
JNZ DISS46 ; NO - WRITE ADDRESS TO DISK BUFFER
JMP DISS65 ; YES - WRITE "END" TO OUTPUT FILE
DISS46:
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV BYTE PTR[BX],'0'; LOAD LEADING ZERO
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV AL,[BX] ; LOAD NEXT BYTE
INC BX ; ADVANCE POINTER
MOV MEMPTR,BX ; STORE
CALL EXPAND ; CONVERT TO ASCII IN DISK BUFFER
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
JMP DISS60 ; WRITE "TAB,;,CR,LF" TO OUTPUT FILE
DISS50:
MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
MOV MEMCNT,BX ; (STORE)
JNZ DISS51 ; NO - WITE LINE END TO DISK BUFFER
JMP DISS65 ; YES - WRITE "END" TO OUTPUT FILE
DISS51:
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV AL,[BX] ; LOAD NEXT BYTE
INC BX ; ADVANCE POINTER
MOV MEMPTR,BX ; STORE
CALL EXPAND ; CONVERT TO ASCII IN DISK BUFFER
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
JMP DISS60 ; WRITE "TAB,;,CR,LF" TO OUTPUT FILE
DISS55:
MOV BX,MEMCNT ; LOAD MEMORY BUFFER COUNTER
DEC BX ; RETARD MEMORY BUFFER COUNTER - LAST BYTE?
MOV MEMCNT,BX ; (STORE)
JNZ DISS56 ; NO - WRITE ADDRESS TO DISK BUFFER
JMP DISS65 ; YES - WRITE "END" TO OUTPUT FILE
DISS56:
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
PUSH BX ;
POP DX ; IN DX
MOV BX,OFFSET MEMBUF; LOAD MEMORY BUFFER ADDRESS
MOV AL,DL ; LOAD LOW MEMORY BUFFER POINTER
SUB AL,BL ; SUBTRACT LOW MEMORY BUFFER ADDRESS
MOV AL,DH ; LOAD HIGH MEMORY BUFFER POINTER
SBB AL,BH ; COMPUTE PAGE NUMBER
CALL EXPAND ; WRITE PAGE NUMBER TO DISK BUFFER
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV AL,[BX] ; LOAD NEXT BYTE
INC BX ; ADVANCE POINTER
MOV MEMPTR,BX ; STORE
CALL EXPAND ; CONVERT TO ASCII IN DISK BUFFER
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
DISS60:
MOV CX,DSKCNT ; LOAD DISK BUFFER COUNTER
MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
DISS61:
MOV CH,0 ; CLEAR CHARACTER COUNTER
DISS62:
MOV AL,[BX] ; LOAD NEXT CHARACTER
INC BX ; ADVANCE DISK BUFFER POINTER
INC CH ; ADVANCE CHARACTER COUNTER
DEC CL ; LAST CHARACTER?
JZ DISS63 ; YES - DECIDE WHETHER ONE OR TWO TABS
CMP AL,TAB ; NO - TAB?
JZ DISS61 ; YES - CLEAR CHARACTER COUNTER
JMP DISS62 ; NO - TEST NEXT CHARACTER
DISS63:
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV AL,8 ;
CMP AL,CH ; LESS THAN EIGHT CHARACTERS SINCE LAST TAB?
JBE DISS66 ; NO - WRITE ONE TAB TO DISK BUFFER
MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
INC DSKCNT ; ADVANCE DISK BUFFER COUNTER
DISS66:
MOV BYTE PTR[BX],TAB; WRITE TAB TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV BYTE PTR[BX],';'; WRITE ";" TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV BYTE PTR[BX],' '; WRITE " " TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV DSKPTR,BX ; STORE
MOV DX,CURADD ; LOAD CURRENT ADDRESS
MOV AL,DH ; LOAD HIGH ADDRESS
CALL EXPAND ; WRITE TO DISK BUFFER
MOV AL,DL ; LOAD LOW ADDRESS
CALL EXPAND ; WRITE TO DISK BUFFER
MOV BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
INC BX ; ADVANCE DISK BUFFER POINTER
MOV BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
ADD DSKCNT,5 ; ADD TAB AND TERMINATOR COUNT
DISKWR DSKCNT ; WRITE TO DISK - ERROR?
CMP AX,DSKCNT ; NO - ALL BYTES WRITTEN?
JZ DISS64 ; YES - CONTINUE
MOV AX,0 ; NO - LOAD ERROR NUMBER
JMP DSKERR ; NO - DISPLAY ERROR
DISS64:
JMP DISS05 ; CONTINUE
DISS65:
MOV BX,OFFSET MSGEND; POINT TO "END" STRING
MOV DI,OFFSET DSKBUF; POINT TO DISK BUFFER
MOV CX,LENEND ; LOAD MESSAGE LENGTH
DISS70:
MOV AL,[BX] ; LOAD FROM STRING
MOV [DI],AL ; WRITE TO DISK BUFFER
INC BX ; ADVANCE STRING POINTER
INC DI ; ADVANCE DISK BUFFER POINTER
DEC CX ; RETARD COUNTER - DONE?
JNZ DISS70 ; NO - CONTINUE
DISKWR LENEND ; YES - WRITE TO DISK - ERROR?
CMP AX,LENEND ; NO - ALL BYTES WRITTEN?
JZ DISS75 ; YES - DONE
MOV AX,0 ; NO - LOAD ERROR NUMBER
JMP DSKERR ; DISPLAY ERROR
DISS75:
RET ; DONE
DISS ENDP ;
PAGE
; ****************************************************************
; ** **
; ** CLOSE OUTPUT FILE **
; ** **
; ****************************************************************
CLOSWR PROC NEAR ;
MOV AH,CLOSE ; LOAD CLOSE FILE COMMAND
MOV BX,WRHAND ; LOAD OUTPUT FILE HANDLE
INT DOSFUNC ; CLOSE THE OUTPUT FILE - ERROR?
JNC CLOS05 ; NO - DONE
JMP DSKERR ; YES - DISPLAY ERROR
CLOS05:
RET ;
CLOSWR ENDP
PAGE
SBRS PROC NEAR ;
; ****************************************************************
; ** **
; ** SUBROUTINES **
; ** **
; ****************************************************************
; ****************************************************************
; ** FUNCTION: CONVERT ASCII TO HEXADECIMAL **
; ** ENTRY: ASCII REPRESENTATION OF VALID HEX NUMBER IN AL **
; ** USES: AL **
; ** EXIT: HEX NUMBER IN AL **
; ** CALLS: NONE **
; ****************************************************************
ASCHEX:
CMP AL,'9'+1 ; IS IT LESS THAN OR EQUAL TO 9?
JLE ASC05 ; YES - JUMP PAST HEX CONVERSION
ADD AL,9 ; NO - ADD HEX OFFSET
ASC05:
AND AL,0FH ; STRIP ASCII BIAS
RET ;
PAGE
; ****************************************************************
; ** FUNCTION: CONVERT 8 BIT VALUE TO TWO ASCII CHARACTERS **
; ** AND WRITE THEM TO MEMORY POINTED TO BY DSKPTR **
; ** ENTRY: A=8 BIT VALUE TO BE CONVERTED **
; ** USES: BX **
; ** EXIT: BX=END VALUE OF DSKPTR **
; ** CALLS: HEXASC **
; ****************************************************************
EXPAND:
PUSHF ;
PUSH AX ;
PUSH CX ;
PUSH AX ; SAVE BYTE TO BE EXPANDED
MOV CL,4 ;
ROL AL,CL ; EXCHANGE NIBBLES
CALL HEXASC ; CONVERT HEX TO ASCII
MOV BX,DSKPTR ; LOAD DISK BUFFER POINTER
MOV [BX],AL ; WRITE TO MEMORY
INC BX ; ADVANCE MEMORY POINTER
POP AX ; RESTORE ORIGINAL BYTE
CALL HEXASC ; CONVERT HEX TO ASCII
MOV [BX],AL ; WRITE TO MEMORY
INC BX ; ADVANCE MEMORY POINTER
MOV DSKPTR,BX ; STORE NEW DISK BUFFER POINTER
MOV AX,DSKCNT ; LOAD DISK BUFFER COUNTER
INC AX ;
INC AX ; ADVANCE
MOV DSKCNT,AX ; STORE
POP CX ;
POP AX ;
POPF ;
RET ;
; ****************************************************************
; ** FUNCTION: CONVERT 4 BIT VALUE TO ASCII **
; ** ENTRY: LOWER NIBBLE OF A=VALUE TO BE CONVERTED **
; ** USES: AL **
; ** EXIT: A=ASCII CHARACTER **
; ** CALLS: NONE **
; ****************************************************************
HEXASC:
AND AL,0FH ; ISOLATE LOWER NIBBLE
CMP AL,9+1 ; IS IT LESS THAN OR EQUAL TO 9?
JL HXAS05 ; YES - JUMP PAST HEX CONVERSION
SUB AL,9 ; NO - SUBTRACT HEX OFFSET
OR AL,40H ; COMBINE WITH HEX ASCII BIAS
RET ;
HXAS05:
OR AL,30H ; COMBINE WITH DECIMAL ASCII BIAS
RET ;
PAGE
; ****************************************************************
; ** FUNCTION: WRITE MESSAGE TO STANDARD OUTPUT **
; ** ENTRY: DX=START ADDRESS OF MESSAGE STRING **
; ** USES: ??? **
; ** EXIT: NONE **
; ** CALLS: NONE **
; ****************************************************************
MSGCO:
MOV AH,PR_STR ; LOAD PRINT STRING COMMAND
INT DOSFUNC ; PRINT STRING
RET ; DONE
PAGE
; ****************************************************************
; ** FUNCTION: COMPUTE NUMBER OF BYTES FOR OP-CODES **
; ** ENTRY: CX=OPCODE **
; ** USES: CL **
; ** EXIT: NUMBER OF BYTES IN CL **
; ** CALLS: NONE **
; ****************************************************************
OPBYTE:
PUSH BX ; SAVE BX
MOV BX,OFFSET BYTES ; POINT TO BYTES TABLE
ADD BX,CX ; ADD OFFSET
MOV CL,[BX] ; LOAD NUMBER OF BYTES
POP BX ; RESTORE BX
RET ;
; ****************************************************************
; ** FUNCTION: WRITE ORG STRING TO DISK **
; ** ENTRY: NONE **
; ** USES: ALL **
; ** EXIT: ORG STRING WRITTEN TO DISK **
; ** CALLS: EXPAND **
; ****************************************************************
ORGWR:
MOV DSKCNT,0 ; CLEAR DISK BUFFER COUNTER
MOV CX,LENORG ; LOAD "ORG" MESSAGE LENGTH
MOV DI,OFFSET MSGORG; POINT TO "ORG" STRING
MOV BX,OFFSET DSKBUF; POINT TO DISK BUFFER
ORGW05:
MOV AL,[DI] ; LOAD NEXT CHARACTER OF "ORG" STRING
MOV [BX],AL ; WRITE IT TO DISK BUFFER
INC DI ;
INC BX ; ADVANCE POINTERS
INC DSKCNT ; ADVANCE DISK BUFFER COUNTER
DEC CX ; DECREMENT COUNTER - DONE?
JNZ ORGW05 ; NO - CONTINUE
MOV DSKPTR,BX ; YES - STORE DISK BUFFER POINTER
MOV DX,OFFSET MEMBUF; LOAD MEMORY BUFFER ADDRESS
MOV BX,MEMPTR ; LOAD MEMORY BUFFER POINTER
MOV AL,BL ; LOAD LOW MEMORY BUFFER POINTER
SUB AL,DL ; COMPUTE LOW ORG ADDRESS
PUSH AX ; STORE
MOV AL,BH ; LOAD HIGH MEMORY BUFFER POINTER
SBB AL,DH ; COMPUTE HIGH ORG ADDRESS
CALL EXPAND ; WRITE TO DISK BUFFER
POP AX ; LOAD LOW ORG ADDRESS
CALL EXPAND ; WRITE TO DISK BUFFER
MOV BYTE PTR[BX],'H'; WRITE HEX INDICATOR TO DISK BUFFER
INC BX ; ADVANCE POINTER
MOV BYTE PTR[BX],CR ; WRITE <CR> TO DISK BUFFER
INC BX ; ADVANCE POINTER
MOV BYTE PTR[BX],LF ; WRITE LINE FEED TO DISK BUFFER
ADD DSKCNT,3 ; ADJUST DISK BUFFER COUNTER
DISKWR DSKCNT ; WRITE DKSCNT BYTES TO DISK - ERROR?
CMP AX,DSKCNT ; NO - ALL BYTES WRITTEN?
JZ ORGW10 ; YES - DONE
POP AX ; NO - RESTORE STACK
MOV AX,0 ; LOAD ERROR NUMBER
JMP DSKERR ; DISPLAY ERROR
ORGW10:
RET ; DONE
; ****************************************************************
; ** FUNCTION: CONVERT TWO ASCII CHARACTERS TO 8 BIT NUMBER **
; ** ENTRY: BX=START ADDRESS OF VALID ASCII HEX CHARACTERS **
; ** USES: AL, BX **
; ** EXIT: AL=8 BIT NUMBER, BX=BX+2 **
; ** CALLS: ASCHEX **
; ****************************************************************
PACK:
PUSH CX ; SAVE CX
MOV AL,[BX] ; LOAD CHARACTER
CALL ASCHEX ; CONVERT ASCII CHARACTER TO HEX
MOV CL,4 ;
ROL AL,CL ; EXCHANGE NIBBLES
MOV CH,AL ; STORE
INC BX ; POINT TO NEXT CHARACTER
MOV AL,[BX] ; LOAD NEXT CHARACTER
CALL ASCHEX ; CONVERT ASCII CHARACTER TO HEX
OR AL,CH ; COMBINE NIBBLES
INC BX ; POINT TO NEXT CHARACTER
ADD CHKACC,AL ; UPDATE CHECKSUM ACCUMULATOR
POP CX ; RESTORE CX
RET ;
SBRS ENDP ;
PAGE
ERRHAN PROC FAR
; ****************************************************************
; ** **
; ** DISK ERROR HANDLER **
; ** **
; ****************************************************************
DSKERR:
MOV DX,OFFSET MDISK0; POINT TO DISK ERROR MESSAGE 0
OR AX,AX ; ERROR 0?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK1; NO - POINT TO DISK ERROR MESSAGE 1
DEC AX ; ERROR 1?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK2; NO - POINT TO DISK ERROR MESSAGE 2
DEC AX ; ERROR 2?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK3; NO - POINT TO DISK ERROR MESSAGE 3
DEC AX ; ERROR 3?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK4; NO - POINT TO DISK ERROR MESSAGE 4
DEC AX ; ERROR 4?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK5; NO - POINT TO DISK ERROR MESSAGE 5
DEC AX ; ERROR 5?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MDISK6; NO - POINT TO DISK ERROR MESSAGE 6
DEC AX ; ERROR 6?
JZ MISERR ; YES - DISPLAY ERROR MESSAGE
MOV DX,OFFSET MUKNOW; NO - POINT TO UNKNOWN DISK ERROR MESSAGE
JMP MISERR ; DISPLAY ERROR MESSAGE
; ****************************************************************
; ** **
; ** MISCELANEOUS ERROR HANDLER **
; ** **
; ****************************************************************
MISERR:
CALL MSGCO ; WRITE MESSAGE TO STANDARD OUTPUT
POP AX ; RESTORE STACK
RET ; RETURN TO DOS
ERRHAN ENDP ;
CODE ENDS ;
END DASM48 ;